package com.mijie.core;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;

import net.sf.json.JSONObject;

import com.mijie.util.GeoUtil;
import com.mijie.util.HttpUtil;

public final class RegionInfoFinder {

	private Map<Integer,Map<Integer,List<RegionInfo>>> regionInfomap = new HashMap<Integer,Map<Integer,List<RegionInfo>>>();
	
	protected RegionInfoFinder(InputStream is) throws Exception{
		 InputStreamReader isr = null;
		 BufferedReader br = null;
		 try{
			 isr = new InputStreamReader(is);
			 br = new BufferedReader(isr);
			 String line = null;
			 String[] entry = null;
			 Map<Integer,List<RegionInfo>> latMap = null;
			 List<RegionInfo> infoList = null;
			 RegionInfo info = null;
			 while((line=br.readLine())!=null){
				 entry = line.split(",");
				 if(entry.length!=9) return;
				 //52,122,52.9707310169,122.5315431547,黑龙江省,大兴安岭地区,漠河县,黑龙江,大兴安岭
				 info = new RegionInfo();
				 info.setLatitudePrefix(Integer.parseInt(entry[0]));
				 info.setLongitudePrefix(Integer.parseInt(entry[1]));
				 info.setLatitude(Double.parseDouble(entry[2]));
				 info.setLongitude(Double.parseDouble(entry[3]));
				 info.setProvince(entry[4]);
				 info.setCity(entry[5]);
				 info.setDistrict(entry[6]);
				 info.setSimpleProvince(entry[7]);
				 info.setSimpleCity(entry[8]);
				 
				 latMap = regionInfomap.get(info.getLongitudePrefix());
				 if(latMap==null) latMap =  new HashMap<Integer,List<RegionInfo>>();
				 infoList = latMap.get(info.getLatitudePrefix());
				 if(infoList==null) infoList = new ArrayList<RegionInfo>();
				 infoList.add(info);
				 latMap.put(info.getLatitudePrefix(), infoList);
				 regionInfomap.put(info.getLongitudePrefix(), latMap);
			 }
		 }catch(Exception e){
			throw e;
		 }finally{
			 try{
				 if(br!=null) br.close();
				 if(isr!=null) isr.close();
			 }catch(IOException ex){}
		 }
	}
	
	public int size(){
		return this.regionInfomap.size();
	}
	
	public RegionInfo findRegionInfo(double latitude,double longitude){
		RegionInfo info = null;
		
		String content = null;
		try {
			String url = GeoUtil.baiduMapApi+"&location="+latitude+","+longitude;
			content = HttpUtil.request(url, "GET", "UTF-8", null);
			
			if(content!=null){
				JSONObject json = JSONObject.fromObject(content);
				String status = json.getString("status");
				if("OK".equalsIgnoreCase(status)){
					json = json.getJSONObject("result").getJSONObject("addressComponent");
					String province = json.getString("province").trim();
					if(!province.isEmpty()){
						String city = json.getString("city").trim();
						String district = json.getString("district").trim();
						info = new RegionInfo();
						info.setProvince(province);
						info.setCity(city);
						info.setDistrict(district);
						info.setLatitude(latitude);
						info.setLongitude(longitude);
						info.setSimpleProvince(info.getProvince());
						info.setSimpleCity(info.getCity());
						
						if(province.length()==3){
							info.setSimpleProvince(province.substring(0,2));
						}else if(province.length()!=2){
							for(String p : GeoUtil.SPECIAL_PROVINCES){
								if(province.contains(p)){
									info.setSimpleProvince(p);
									break;
								}
							}
						}
						
						if(city.length()==3){
							info.setSimpleCity(city.substring(0,2));
						}else if(city.contains("市")){
							info.setSimpleCity(city.substring(0,city.lastIndexOf("市")));
						}else if(city.contains("地区")){
							info.setSimpleCity(city.substring(0,city.lastIndexOf("地区")));
						}else if(city.contains("自治州")){
							Matcher m = GeoUtil.CITY_PATTERN.matcher(city);
							info.setSimpleCity(m.replaceAll(""));
						}
					}
				}
			}
		} catch (Exception e) {
			
		}
		
		if(info!=null) return info;
		
		String latPrefix = String.valueOf(latitude);
		latPrefix = latPrefix.substring(0,latPrefix.indexOf("."));
		String lonPrefix = String.valueOf(longitude);
		lonPrefix = lonPrefix.substring(0,lonPrefix.indexOf("."));
		
		Map<Integer,List<RegionInfo>> latMap = regionInfomap.get(Integer.parseInt(lonPrefix));
		if(latMap!=null){
			List<RegionInfo> infoList = latMap.get(Integer.parseInt(latPrefix));
			if(infoList!=null && !infoList.isEmpty()){
				RegionInfo ri = null;
				double min = Double.MAX_VALUE;
				int minAtIndex = 0;
				for(int i=0;i<infoList.size();i++){
					ri = infoList.get(i);
					double dis = GeoUtil.getDistance(longitude, latitude, ri.getLongitude(), ri.getLatitude());
					if(dis<min){
						min = dis;
						minAtIndex = i;
					}
				}
				info = infoList.get(minAtIndex);
			}
		}
		
		return info;
	}
}
